using System;
using System.Collections.Generic;
using System.Text;

using QLTDK.Entities.Base;

namespace QLTDK.DataAccess.Interfaces.Base
{
    /// <summary>
    /// Provides a generic interface for DAOs
    /// </summary>
    /// <typeparam name="T">The type of entity that DAO is created for, it must inherit EntityObject</typeparam>
    /// <typeparam name="IdT">The type of primary key of entity</typeparam>
    public interface IGenericDao<T, IdT> : IDao where T : EntityObject<IdT>
    {
        #region Method

        #region Get Methods

        /// <summary>
        /// Returns null if a row is not found matching the provided Id.
        /// </summary>
        T GetById(IdT id);

        /// <summary>
        /// Returns all of the items of a given type.
        /// </summary>
        IList<T> GetAll();

        /// <summary>
        /// Returns all of the items of a given type.
        /// </summary>
        IList<T> GetAll(int maxResults);
		
        /// <summary>
        /// Looks for zero or more instances using the example provided.
        /// </summary>
        IList<T> FindAll(T exampleInstance, params string[] propertiesToExclude);

        /// <summary>
        /// Looks for zero or more instances using the example provided.
        /// </summary>
        IList<T> FindAll(T exampleInstance, int maxResults, params string[] propertiesToExclude);
		
        /// <summary>
        /// Looks for a single instance using the example provided.
        /// Throw an exception if there are more than one instance.
        /// </summary>
        /// <exception cref="NonUniqueResultException" />
        T FindOne(T exampleInstance, params string[] propertiesToExclude);

        #endregion

        #region CRUD Methods

        /// <summary>
        /// For entities that have assigned Id's, you must explicitly call Save to add a new one.
        /// See http://www.hibernate.org/hib_docs/nhibernate/html_single/#mapping-declaration-id-assigned.
        /// </summary>
        T Save(T entity);

        /// <summary>
        /// For entities with automatatically generated Ids, such as identity, SaveOrUpdate may 
        /// be called when saving or updating an entity.
        /// 
        /// Updating also allows you to commit changes to a detached object.  More info may be found at:
        /// http://www.hibernate.org/hib_docs/nhibernate/html_single/#manipulatingdata-updating-detached
        /// </summary>
        T SaveOrUpdate(T entity);

        /// <summary>
        /// Remove entities of database.
        /// </summary>
        void Delete(T entity);

        /// <summary>
        /// For entities that have assigned Id's, you should explicitly call Update to update an existing one.
        /// Updating also allows you to commit changes to a detached object.  More info may be found at:
        /// http://www.hibernate.org/hib_docs/nhibernate/html_single/#manipulatingdata-updating-detached
        /// </summary>
        T Update(T entity);

        #endregion

        #endregion

    }
}

